package org.example.component;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component // <bean id="txManager" class="org.example.component.TransactionManagerHandler"/>
@Aspect //声明当前类是Spring的AOP切面配置类  <aop:aspect ref="txManager">
public class TransactionManagerHandler {

    /**
     * @Pointcut("切入点语法")
     * 配置切入点，方法名等价于xml配置的id值
     */
    @Pointcut("execution(* org.example.service..*.*(..))") // <aop:pointcut id="pt" expression="execution(* org.example.service..*.*(..))"/>
    public void pt(){

    }


    /**
     *
     * @param joinPoint
     */
    //@Before("pt()") // <aop:before method="begin"  pointcut-ref="pt"/>
    public void begin(JoinPoint joinPoint) {

        Object target = joinPoint.getTarget();//真是对象
        System.out.println("target = " + target);
        Object[] args = joinPoint.getArgs();
        System.out.println("args = " + Arrays.toString(args));

        System.out.println("==开启事务==注解");
    }

    //@AfterReturning("pt()") //<aop:after-returning method="commit" pointcut-ref="pt"/>
    public void commit() {
        System.out.println("提交事务==注解");
    }

    //@AfterThrowing(pointcut = "pt()",throwing = "e") //<aop:after-throwing method="rollback" pointcut-ref="pt" throwing="ex"/>
    public void rollback(Throwable e) {
        System.out.println("回滚事务==注解");
    }
    //@After("pt()") //<aop:after method="close" pointcut-ref="pt"/>
    public void close() {
        System.out.println("关闭session==注解");
    }


    //=================环绕通知===========================

    @Around("pt()")
    public void allInOne(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("=================环绕通知===========================");
        begin(joinPoint);
        try {
            //执行方法
            joinPoint.proceed();

            commit();
        } catch (Exception e) {
            rollback(e);
            throw new RuntimeException(e);
        } finally {
            close();
        }
    }
}